package com.transfiguro.visitors;

import com.transfiguro.datamodel.javamodels.Method;
import com.transfiguro.utilities.Utilities;
import japa.parser.ast.body.ConstructorDeclaration;
import japa.parser.ast.stmt.BlockStmt;
import japa.parser.ast.stmt.Statement;
import japa.parser.ast.visitor.VoidVisitorAdapter;

import java.util.ArrayList;
import java.util.List;

/**
 * This class provides functions to visit the constructor of a given class
 * and build a {@link Method} out of it
 */
public class ConstructorVisitor extends VoidVisitorAdapter {
    private Method method;
    private StatementVisitor statementVisitor;
    private List<com.transfiguro.datamodel.Statement> statements;


    /**
     * Constructor
     */
    public ConstructorVisitor() {
        statementVisitor = new StatementVisitor();
        statements = new ArrayList<com.transfiguro.datamodel.Statement>();
        method = new Method();
    }

    /**
     * This method visits different nodes in a {@link ConstructorDeclaration} and builds
     * a {@link Method} out of it
     *
     * @param constructorDeclaration  The <code>ConstructorDeclaration</code> that has to be parsed
     * @param arg                     Optional argument that can be used to pass anything into the function
     */
    @Override
    public void visit(final ConstructorDeclaration constructorDeclaration, final Object arg) {
        if (constructorDeclaration != null) {
            method.setMethodName(constructorDeclaration.getName());
            method.setInputParameters(Utilities.getInputParameters(constructorDeclaration.getParameters()));
            method.setMethodBody(constructorDeclaration.getBlock().toString());
            method.setReturnType("");
            final BlockStmt blockStmt = constructorDeclaration.getBlock();
            if (blockStmt.getStmts() != null) {
                for (final Statement statement : blockStmt.getStmts()) {
                    statements.add(statementVisitor.visit(statement));
                }
            }
            method.setStatements(statements);
            method.setAccessModifier(constructorDeclaration.getModifiers());
            method.setComment(Utilities.getComment(constructorDeclaration.getJavaDoc()));
        }
    }

    /**
     * Getter for <code>method</code>
     *
     * @return  The <code>method</code> created by visiting the nodes in the given
     *         <code>ConstructorDeclaration</code>
     */
    public Method getMethod() {
        return method;
    }

}
